package com.chr.hongyun.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.chr.hongyun.config.shiro.JwtUtil;
import com.chr.hongyun.dao.TbDeptDao;
import com.chr.hongyun.dao.TbUserDao;
import com.chr.hongyun.exception.HongyunException;
import com.chr.hongyun.pojo.MessageEntity;
import com.chr.hongyun.pojo.TbUser;
import com.chr.hongyun.service.UserService;
import com.chr.hongyun.task.MessageTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
@Scope("prototype")
public class UserServiceImpl implements UserService {
    @Value("${wx.app-id}")
    private String appId;

    @Value("${wx.app-secret}")
    private String appSecret;

    @Autowired
    private TbUserDao userDao;

    @Autowired
    private TbDeptDao deptDao;

    @Autowired
    private MessageTask messageTask;

    /**
     * 获取OpenId
     *
     * @param code
     * @return
     */
    private String getOpenId(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        HashMap map = new HashMap();
        map.put("appid", appId);
        map.put("secret", appSecret);
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String response = HttpUtil.post(url, map);
        JSONObject json = JSONUtil.parseObj(response);
        String openId = json.getStr("openid");
        if (openId == null || openId.length() == 0) {
            throw new RuntimeException("临时登录凭证错误");
        }
        return openId;
    }

    /**
     * @param registerCode 邀请码
     * @param code         临时密码,使用过一次之后就会过期
     * @param nickname     员工名 非真实姓名
     * @param photo        员工头像
     * @return
     */
    @Override
    public int registerUser(String registerCode, String code, String nickname, String photo) {
        String openId = getOpenId(code);
        //bool表示该员工是否注册过
        boolean bool = userDao.ifHasUser(openId);
        if (!bool) {
            //00开头代表该员工为超级管理员,10开头代表总经理,超级管理员不属于任何部门,总经理属于管理部
            //10代表部门经理,11代表普通员工
            int roleId = Integer.parseInt(registerCode.substring(0, 2), 2);
            //deptId表示部门编号
            int deptId = Integer.parseInt(registerCode.substring(2, 6), 2);
            if (roleId == 0) {
                if (userDao.ifHasAdmin()) {
                    throw new HongyunException("已有超级管理员,请输入正确的邀请码!");
                }
            } else if (roleId == 1) {
                if (userDao.ifHasManager()) {
                    throw new HongyunException("已有总经理,请输入正确的邀请码!");
                }
            } else if (roleId == 2) {
                if (userDao.ifHasCharge(deptId)) {
                    throw new HongyunException("该部门已有经理,请输入正确的邀请码!");
                }
            }

            //查询部门名称
            String deptName = deptDao.selectDeptNameById(deptId);
            if (!(deptName != null && deptName.length() > 0)) {
                throw new HongyunException("该部门不存在,请重新输入邀请码");
            }

            //注册员工
            HashMap param = new HashMap();
            param.put("openId", openId);
            param.put("nickname", nickname);
            param.put("name",nickname);
            param.put("photo", photo);
            param.put("roleId", roleId);
            param.put("deptId", deptId);
            param.put("status", 1);
            param.put("createTime", new Date());
            userDao.insertUser(param);

            //系统通知员工尽快更新个人信息
            int id = userDao.searchIdByOpenId(openId);
            MessageEntity entity = new MessageEntity();
            entity.setSenderId(0);
            entity.setUuid(IdUtil.simpleUUID());
            entity.setSendPhoto(photo);
            entity.setSendName("系统消息");
            entity.setMsg("欢迎您注册,请及时更新你的个人信息");
            entity.setSendTime(new Date());
            messageTask.sendAsync(id + "", entity);
            return id;
        } else {
            throw new HongyunException("您已注册,请勿重复注册!");
        }
    }

    @Override
    public Set<String> searchUserPermissions(int userId) {
        Set<String> permissions = userDao.searchUserPermissions(userId);
        return permissions;
    }

    @Override
    public Integer login(String code) {
        String openId = getOpenId(code);
        Integer id = userDao.searchIdByOpenId(openId);
        if (id == null) {
            throw new HongyunException("账户不存在,请先注册");
        }
//        messageTask.receiveAsync(id + "");
        return id;
    }

    @Override
    public TbUser searchById(int userId) {
        TbUser user = userDao.searchById(userId);
        return user;
    }

    @Override
    public String searchUserHireDate(int userId) {
        String hireDate = userDao.searchUserHireDate(userId);
        return hireDate;
    }

    @Override
    public HashMap searchUserSummary(int userId) {
        HashMap map = userDao.searchUserSummary(userId);
        return map;
    }

    @Override
    public ArrayList<HashMap> searchUserGroupByDept(String keyword, int userId) {
        // 获取当前角色
        TbUser user = userDao.searchById(userId);
        Integer roleId = user.getRoleId();
        HashMap param = new HashMap();
        if (roleId == 2) param.put("deptId", user.getDeptId());
        param.put("keyword", keyword);
        //分组查询各部门人数
        ArrayList<HashMap> list_1 = deptDao.searchDeptMembers(param);
        //查询员工的部门编号,部门名,员工编号,员工姓名
        ArrayList<HashMap> list_2 = userDao.searchUserGroupByDept(param);
        for (HashMap map_1 : list_1) {
            Long deptId = (Long) map_1.get("id");
            ArrayList members = new ArrayList();
            for (HashMap map_2 : list_2) {
                Long id = (Long) map_2.get("deptId");
                if (deptId == id) {
                    members.add(map_2);
                }
            }
            map_1.put("members", members);
        }
        //list_1是合并后的数据,里面既有部门人数,又有个员工的详细部门信息
        return list_1;
    }

    @Override
    public ArrayList<HashMap> searchMembers(List param) {
        ArrayList<HashMap> list = userDao.searchMembers(param);
        return list;
    }

    @Override
    public HashMap searchUserInfo(int userId) {
        HashMap map = userDao.searchUserInfo(userId);
        return map;
    }

    @Override
    public void updateUserInfo(HashMap param) {
        int row = userDao.updateUserInfo(param);
        if (row < 0) {
            throw new HongyunException("员工更新个人信息异常");
        }
    }
}
